iT邦幫忙

2024 iThome 鐵人賽

DAY 6
1
Modern Web

欸你是要進 Vue 了沒?系列 第 6

欸你是要進 Vue 了沒? - Day6:Vue 專案你是怎麼組起來的?從根組件看組件之間的互動關係

  • 分享至 

  • xImage
  •  

大家好!承前兩天,我們使用 Vite 建置了 Vue 專案,並且理解了它的資料夾結構,今天一起來更深入看一下這個專案是怎麼「組」起來的。
/images/emoticon/emoticon08.gif

從 App.vue 根組件來看

App.vue 中可以看到 SFC 的結構,由 <script setup></script><template></template><style></style> 組成。
https://ithelp.ithome.com.tw/upload/images/20240919/20169139FYl50RPvWG.png

繼續看看這些區塊都做了什麼事!

script setup

引入了 src/component 中的 HelloWorldTheWelcome 這兩個組件。

https://ithelp.ithome.com.tw/upload/images/20240919/20169139HPRrvIQWht.png

以 HelloWorld 來看

HelloWorld 被使用在 <div class="wrapper"> 中的區塊。
https://ithelp.ithome.com.tw/upload/images/20240919/20169139KLg0GRIf0o.png

我們到 HelloWorld.vue 裡看它做了什麼事:
https://ithelp.ithome.com.tw/upload/images/20240919/20169139Lcp29duSuK.png

<script setup></script> 中使用了以下語法:

<script setup>
defineProps({
  msg: {
    type: String,
    required: true
  }
})
</script>

defineProps(Props 意為 property)中定義了:

  1. msg: {}:指定 msg 為組件的屬性。
  2. type: String:定義 msg 屬性的類型為 String
  3. required: true:msg 屬性是必須提供的。

defineProps() 的作用是:告訴子組件要「接收哪些數據」,並且這些數據必須來自「父組件」。
所以,父組件 import 這個子組件時,必須提供一個「字符串型的 msg property」,否則會報錯。

因此!App.vue 根組件 import HelloWorld 的時候,要提供 defineProps 裡定義的東西。

<template></template> 定義了基本的組件 html 結構。

<template>
  <div class="greetings">
    <h1 class="green">{{ msg }}</h1>
    <h3>
      You’ve successfully created a project with
      <a href="https://vitejs.dev/" target="_blank" rel="noopener">Vite</a> +
      <a href="https://vuejs.org/" target="_blank" rel="noopener">Vue 3</a>.
    </h3>
  </div>
</template>

它做了什麼事?

<h1 class="green">{{ msg }}</h1>:這裡的 {{ msg }} 是 Vue 中的「文本插值」,代表當父組件傳遞一個 msg 的屬性時,它會在 <h1> 標籤中顯示內容 {{ msg }}

那什麼時候「父組件會傳遞一個 msg」???

回頭看一下 App.vue 做了什麼:
https://ithelp.ithome.com.tw/upload/images/20240919/20169139kfo1piYl9h.png
<HelloWorld /> 定義了「屬性:msg」和「值:You did it」。

也就是剛剛提到的!子組件 HelloWorld 定義了 defineProps(),所以這些數據會由父組件傳到 HelloWorld{{ msg }} 處。

插播!為什麼可以用 HelloWorld 這種 tag 呢?

這是因為 Vue 中有「自定義標籤」的特性,當我們將組件 import 到某個檔案,相等於我們將該組件定義為一個變數,並且我們可以在該檔案中用該變數做事。
所以 import HelloWorld from './components/HelloWorld.vue' 讓我們可以在這邊用 HelloWorld 作為自定義標籤,並渲染 HelloWorld.vue 組件的內容。

TheWelcomeApp.vue 中也是用了自定義標籤,目前看起來就是將 TheWelcome 這個組件的東東塞進來。
https://ithelp.ithome.com.tw/upload/images/20240919/20169139DbcdgidkBP.png

看一下 TheWelcome 裡面是什麼!
https://ithelp.ithome.com.tw/upload/images/20240919/20169139E50gpfhqcU.png
看起來也是許多的組件被 import 進來⋯⋯

從開發者工具觀察

我們可以從開發者工具端詳一下東西是怎麼塞?進去的(我看過我覺得挺有感覺 XDDD,有種拼積木的感覺)

這邊我們來看看 HelloWorld 這個組件。
https://ithelp.ithome.com.tw/upload/images/20240919/20169139f6sPhz19Ug.png

App.vue 中使用 <HelloWorld /> 時,會把 HelloWorld.vue 組件的內容插入到 App.vue 的結構,而這些內容會渲染為 App.vue 的一部分,有點像「填充」的過程~

https://ithelp.ithome.com.tw/upload/images/20240919/20169139D9z3Hc1bWx.png

因此,HelloWorld.vue<div class="greetings"></div> 最終會填充到 App.vue<div class="wrapper"> 內的 <HelloWorld /> 標籤所代表的地方。

不過據說 SFC 會經過 JS 編譯成為渲染函式,進而操作虛擬 DOM(這部分還沒有研究,先帶到這邊 QQ)

小結

我自己覺得今天有比較理解 Vue 中組件相互的應用與關係,繼續繼續⋯⋯明天來看看 Vue 的模板語法(自我懷疑小裁判到目前都蠻沈默,繼續保持)
鐵人賽竟然已經完成 1/5 了!/images/emoticon/emoticon30.gif

參考資料


上一篇
欸你是要進 Vue 了沒? - Day5:Vue 專案資料夾你裡面夾了什麼
下一篇
欸你是要進 Vue 了沒? - Day7:Vue 模板語法【Mustache、v-html】
系列文
欸你是要進 Vue 了沒?13
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

1
jeremykuo
iT邦新手 5 級 ‧ 2024-09-20 12:00:02

加油!繼續讓小裁判啞口無言~

++ iT邦新手 5 級 ‧ 2024-09-20 16:42:57 檢舉

迷有問題!

1
Chris
iT邦新手 4 級 ‧ 2024-09-23 09:46:46

自定義 標籤是一個重要的體感結論

++ iT邦新手 5 級 ‧ 2024-09-23 10:09:59 檢舉

/images/emoticon/emoticon35.gif

我要留言

立即登入留言